package com.efast.cafe.framework.filter;

import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

import com.efast.cafe.framework.constant.CommonConstant;
import com.efast.cafe.framework.feign.constant.FeignConstant;
import com.efast.cafe.portal.bean.common.PortalUserSecurityBean;
import com.efast.cafe.util.ConfigUtil;
import com.efast.cafe.util.IpAddressUtil;
import com.efast.cafe.util.StringUtil;


public class MyAuthenticationFilter implements Filter{
	
	private  Logger logger = LoggerFactory.getLogger(MyAuthenticationFilter.class);
	private List<Pattern> patterns;
	
	
	private static final String secretkey = ConfigUtil.getValue(FeignConstant.FEIGN_SECRET_KEY);
	
	public MyAuthenticationFilter(List<Pattern> patterns){
		this.patterns = patterns;
	}

	@Override
	public void init(FilterConfig filterConfig) throws ServletException {
		
		
	}

	@Override
	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
			throws IOException, ServletException {
		HttpServletRequest httpRequest = (HttpServletRequest) request;
	    HttpServletResponse httpResponse = (HttpServletResponse) response;
	    String url = httpRequest.getServletPath();
	    if (!isInclude(url)){
	    	if(url.startsWith(FeignConstant.Scope.FEIGN_SCOPE_PV)){
	    		String token = httpRequest.getHeader(FeignConstant.FEIGN_SECRET_HEADER_KEY);
	    		if(StringUtil.isNullOrBlank(token)
	    				|| !secretkey.equals(token)){
	    			logger.info(url+",The interface can only be called internally.");
	    			httpResponse.setStatus(401);
					return;
	    		}
	    		chain.doFilter(httpRequest, httpResponse);
	    		return;
	    	}
	    	if(url.startsWith(FeignConstant.Scope.FEIGN_SCOPE_PV_AUTH)){
	    		String token = httpRequest.getHeader(FeignConstant.FEIGN_SECRET_HEADER_KEY);
	    		if(StringUtil.isNullOrBlank(token)
	    				|| !secretkey.equals(token)){
	    			logger.info(url+",The interface can only be called internally.");
	    			httpResponse.setStatus(401);
					return;
	    		}
	    	}
	    	HttpSession session = httpRequest.getSession(false);
	    	if(session!=null){
	    		Object uObject = session.getAttribute(CommonConstant.PORTAL_USER_OBJECT);
	    		if(null!=uObject){
	    			PortalUserSecurityBean user = (PortalUserSecurityBean)uObject;
	    			Object flag = session.getAttribute(CommonConstant.CURRENT_LOGIN_USER_FLAG);
	    			if(null!=flag){
	    				logger.info("session_offline...");
	    				httpResponse.setHeader("state", "session_offline");
		    	 		session.invalidate();
		    	 		return;
	    			}
	    			Object urlPathSetObj = session.getAttribute(CommonConstant.CURRENT_LOGIN_USER_PURVIEWSET_SESSIONKEY);
	    			Object allPathSetObj = session.getAttribute(CommonConstant.CURRENT_LOGIN_USER_ALLPURVIEWSET_SESSIONKEY);
	    			HashSet<String> checkauthSet = (HashSet<String>)urlPathSetObj;
	    			HashSet<String> allauthSet = (HashSet<String>)allPathSetObj;
	    			//如果请求的资源 在 系统中有配置 才需要拦截，没有配置的URL不需要拦截
	    			String ctxUrl = httpRequest.getContextPath()+url;
	    			if(allauthSet.contains(ctxUrl)){
	    				if(!checkauthSet.contains(ctxUrl)){
	    					httpResponse.setStatus(403);
	    					return;
	    				}
	    			}
	    			MDC.put(CommonConstant.USERNAME_FIELD, user.getUsername());
	    			MDC.put(CommonConstant.COMPANYCODE_FIELD, user.getCompany_code());
	    			MDC.put("clientIP",IpAddressUtil.getIpAdrress(httpRequest));
		    		chain.doFilter(httpRequest, httpResponse);
		    		return;
	    		}
	    	}
	    	logger.info("session_timeout...");
	    	httpResponse.setHeader("state", "session_timeout");
    		return;
	    	
	    }else{
	    	chain.doFilter(httpRequest, httpResponse);
	    }
	    
	}

	@Override
	public void destroy() {
		// TODO Auto-generated method stub
		
	}

	public void setPatterns(List<Pattern> patterns) {
		this.patterns = patterns;
	}
	
	/**
	   * 是否需要过滤
	   * @param url
	   * @return
	   */
	  private boolean isInclude(String url) {
		if(null!=patterns){
			for (Pattern pattern : patterns) {
			      Matcher matcher = pattern.matcher(url);
			      if (matcher.find()) {
			        return true;
			      }
			}
		}
	    return false;
	  }

}
